home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v10n12.arc
/
DEV.C
< prev
next >
Wrap
Text File
|
1991-05-30
|
6KB
|
208 lines
/*
DEV.C -- display MS-DOS device chain
Copyright (c) 1991 Ziff Communications Co.
PC Magazine * Andrew Schulman
real mode:
Borland C++ 2.0: bcc dev.c
Microsoft C 6.0: cl dev.c
Borland C++ 2.0 (DPMI.C *must* be compiled with -B flag):
bcc -W -DWINDOWS -2 -B dev.c printf.c dpmi.c
rc dev.exe
Microsoft C 6.0:
cl -c -AS -G2sw -Oais -Zpe -W3 -DWINDOWS dev.c printf.c dpmi.c
link /align:16 dev dpmi printf,dev,,/nod slibcew libw,win.def
rc dev.exe
WIN.DEF:
; WIN.DEF -- generic Windows .DEF file
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 10240
STACKSIZE 5120
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>
#ifdef WINDOWS
#include <windows.h>
#include "dpmi.h"
#include "printf.h"
#endif
#ifdef WINDOWS
char *app = "Walk DOS Device Chain";
#define puts(s) MessageBox(NULL, s, app, MB_OK)
#endif
#define fail(s) return puts(s)
#ifndef MK_FP
#define MK_FP(seg, ofs) \
((void far *) (((unsigned long) (seg) << 16) | (ofs)))
#endif
/* some device attribute bits */
#define CHAR_DEV (1 << 15)
#define INT29 (1 << 4)
#define IS_CLOCK (1 << 3)
#define IS_NUL (1 << 2)
#pragma pack(1)
typedef struct DeviceDriver {
struct DeviceDriver far *next;
unsigned attr;
unsigned strategy;
unsigned intr;
union {
unsigned char name[8];
unsigned char blk_cnt;
} u;
} DeviceDriver;
typedef struct {
unsigned char misc[8];
DeviceDriver far *clock;
DeviceDriver far *con;
unsigned char misc2[18];
DeviceDriver nul; /* not a pointer */
// ...
} ListOfLists; // DOS 3.1+
ListOfLists far *get_doslist(void)
{
#ifdef WINDOWS
/*
Call undocumented DOS INT 21h Function 52h via DPMI "Simulate
Real Mode Interrupt" call (INT 31h AX=0300h), and return
the resulting real-mode pointer
*/
RMODE_CALL r;
memset(&r, 0, sizeof(r));
r.eax = 0x5200;
return (dpmi_rmode_intr(0x21, 0, 0, &r)) ? MK_FP(r.es, r.ebx) : 0;
#else
union REGS r;
struct SREGS s;
segread(&s);
s.es = r.x.bx = 0;
r.h.ah = 0x52;
intdosx(&r, &r, &s);
return MK_FP(s.es, r.x.bx);
#endif
}
#ifdef WINDOWS
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
#else
int main(int argc, char *argv[])
#endif
{
ListOfLists far *doslist;
DeviceDriver far *dd;
#ifdef WINDOWS
DeviceDriver far *next;
int mapped;
#endif
#ifdef WINDOWS
if (! (GetWinFlags() & WF_PMODE))
fail("This program requires Windows Standard or Enhanced mode");
if (! dpmi_present())
fail("This program requires DPMI INT 31h services");
#endif
if (! (doslist = get_doslist()))
fail("INT 21h Function 52h not supported");
#ifdef WINDOWS
/* get protected-mode pointer to DOS internal variable table */
doslist = map_real(doslist, sizeof(ListOfLists));
open_display(app);
#endif
/* This block of code double-checks that everything is ok */
/* NUL is part of DOSLIST, not a pointer, so don't need to map */
if (_fmemcmp(doslist->nul.u.name, "NUL ", 8) != 0)
fail("NUL name wrong");
if (! (doslist->nul.attr & IS_NUL))
fail("NUL attr wrong");
#ifdef WINDOWS
/* CON is pointer, so need to map */
dd = map_real(doslist->con, sizeof(DeviceDriver));
#else
dd = doslist->con;
#endif
if (_fmemcmp(dd->u.name, "CON ", 8) != 0)
fail("CON name wrong");
if (! (dd->attr & CHAR_DEV))
fail("CON attr wrong");
#ifdef WINDOWS
free_mapped_seg(dd);
#endif
#ifdef WINDOWS
/* CLOCK$ is also pointer, so need to map */
dd = map_real(doslist->clock, sizeof(DeviceDriver));
#else
dd = doslist->clock;
#endif
if (_fmemcmp(dd->u.name, "CLOCK$ ", 8) != 0)
fail("CLOCK$ name wrong");
if (! (dd->attr & IS_CLOCK))
fail("CLOCK$ attr wrong");
#ifdef WINDOWS
free_mapped_seg(dd);
#endif
/* print out device chain */
dd = &doslist->nul;
#ifdef WINDOWS
for (;;)
{
printf("%Fp ", DosProtToReal(dd)); /* print real-mode addr */
if (dd->attr & CHAR_DEV)
printf("%.8Fs\r\n", dd->u.name);
else
printf("Block dev: %u unit(s)\r\n", dd->u.blk_cnt);
next = dd->next; /* get next pointer */
/* first time through, this will free selector to doslist */
free_mapped_seg(dd); /* THEN free rmode seg */
if (FP_OFF(next) == -1) /* is there a next? */
break;
dd = map_real(next, sizeof(DeviceDriver)); /* map it */
Yield(); /* no message loop in this program, so yield */
}
#else
do {
printf("%Fp\t", dd);
if (dd->attr & CHAR_DEV)
printf("%.8Fs\n", dd->u.name);
else
printf("Block dev: %u unit(s)\n", dd->u.blk_cnt);
dd = dd->next;
} while (FP_OFF(dd->next) != -1);
#endif
#ifdef WINDOWS
if (mapped = get_mapped())
printf("%u remaining mapped selectors!\r\n", mapped);
show_display();
return mapped; /* 0 indicates success */
#else
return 0;
#endif
}